import { _decorator, Component, Node, Vec3, view, PhysicsSystem2D, Contact2DType, Collider2D, IPhysics2DContact, tween, Sprite, Color, Tween, UIOpacity, sp } from 'cc';
import { ShootBomb } from './ShootBomb';
import { ShootBullet } from './ShootBullet';
import { ShootUZI } from './ShootUZI';
import { GameEventType, ItemType } from '../Event/EnumDefine';
import { EventManager } from '../Event/EventManager';
import { BuffDataType, DataConfig } from '../Config/DataConfig';
import Common from '../Config/Common';
import { Block } from '../Block/Block';
const { ccclass, property } = _decorator;

/** 玩家射击管理控制类 */
@ccclass('ShootController')
export class ShootController extends Component {

    @property(sp.Skeleton) // 绑定 Spine 组件
    playerSpine: sp.Skeleton = null;

    @property
    shootInterval: number = 1; // 发射间隔时间（秒）

    private isPlayerWarning = false;
    private playerTween: Tween<Node>;
    /** 是否处于无敌状态 */
    private isInvincible: boolean = false;
    private invincibleTime: number = 6;

    onLoad(): void {
        // EventManager.instance.registerEvent(GameEventType.Player_Scale_Effect, this.scalePlayer, this);
        EventManager.instance.registerEvent(GameEventType.Item_Buff, this.onItemBuff, this);
        EventManager.instance.registerEvent(GameEventType.Player_Status_Update, this.onPlayerDie, this);
    }
    onEnable() {
        // PhysicsSystem2D.instance.enable = true;
        // PhysicsSystem2D.instance.debugDrawFlags = EPhysics2DDrawFlags.All;

        // 注册全局碰撞回调函数
        if (PhysicsSystem2D.instance) {
            PhysicsSystem2D.instance.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
            PhysicsSystem2D.instance.on(Contact2DType.END_CONTACT, this.onEndContact, this);
            PhysicsSystem2D.instance.on(Contact2DType.PRE_SOLVE, this.onPreSolve, this);
            PhysicsSystem2D.instance.on(Contact2DType.POST_SOLVE, this.onPostSolve, this);
        }
    }

    onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        // 只在两个碰撞体开始接触时被调用一次
        const selfNode = selfCollider.node;
        const otherNode = otherCollider.node;
        if (selfNode.name === "Block" && otherNode.name === 'PlayerNode') {
            this.onPlayerCollider(selfNode)
        } else if (selfNode.name === "PlayerNode" && otherNode.name === 'Block') {
            this.onPlayerCollider(otherNode)
        }
    }
    onEndContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        // 只在两个碰撞体结束接触时被调用一次
    }
    onPreSolve(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        // 每次将要处理碰撞体接触逻辑时被调用
    }
    onPostSolve(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        // 每次处理完碰撞体接触逻辑时被调用
    }

    /** 玩家碰撞到数字块处理 */
    onPlayerCollider(blockNode: Node) {
        if (this.isInvincible) {
            return;
        }
        EventManager.instance.triggerEvent(GameEventType.Player_Health_Reduced, null);
        blockNode.getComponent(Block).onDamageByPlayer();
        if (DataConfig.isGameStop) {
            return;
        }
        EventManager.instance.triggerEvent(GameEventType.Flash_Red_Effect, null);
        this.startInvincible(this.invincibleTime);
    }

    onPlayerWarning() {
        if (this.isPlayerWarning) {
            return
        }
        this.isPlayerWarning = true;
        const playerSprite = this.node.getChildByName('Sprite').getComponent(Sprite);
        const originalColor = playerSprite.color.clone(); // 保存原始颜色
        const tweenTarget = tween(this.node)
            .call(() => {
                playerSprite.color = Color.RED; // 闪红
                playerSprite.grayscale = true;
            })
            .delay(3)
            .call(() => {
                playerSprite.grayscale = false;
                playerSprite.color = originalColor;
                this.isPlayerWarning = false;
            })
            .start();
    }

    start() {
        this.getComponent(ShootBullet).startShoot({ itemType: null, buffData: null });
    }

    onItemBuff(params: { itemType: ItemType, buffData: BuffDataType }) {
        if (params.itemType === ItemType.UZI) {
            this.getComponent(ShootUZI).startShoot(params);
        } else if (params.itemType === ItemType.ACT) {
            this.getComponent(ShootBullet).startShoot(params);
        } else if (params.itemType === ItemType.Bomb) {
            this.getComponent(ShootBomb).startShoot(params);
        } else if (params.itemType === ItemType.Trajectory) {
            this.getComponent(ShootBullet).startShoot(params);
        }
    }

    stopShoot() {
        this.getComponent(ShootBullet).stopShoot();
        this.getComponent(ShootBomb).stopShoot();
        this.getComponent(ShootUZI).stopShoot();
    }

    // 检测子弹是否超出屏幕范围
    isBulletOutOfScreen(bullet: Node): boolean {
        const screenSize = Common.instance.getScreenSize();
        const bulletPos = bullet.position;

        // 判断子弹是否超出屏幕范围
        return (
            bulletPos.x < -screenSize.width / 2 ||
            bulletPos.x > screenSize.width / 2 ||
            bulletPos.y < -screenSize.height / 2 ||
            bulletPos.y > screenSize.height / 2
        );
    }

    // 主角缩放动画
    scalePlayer() {
        if (this.playerTween) {
            this.playerTween.stop();
        }
        const player = this.node; // 主角节点
        player.scale = new Vec3(1, 1, 1);
        // 缩小动画
        this.playerTween = tween(player)
            .to(this.shootInterval / 2, { scale: new Vec3(0.8, 0.8, 1) }) // 缩小
            .to(this.shootInterval / 2, { scale: new Vec3(1, 1, 1) }) // 恢复
            .start();
    }

    /**
     * @zh 开始无敌状态
     * @param duration 持续时间
     * @returns 
     */
    startInvincible(duration: number) {
        if (this.isInvincible) return;

        this.isInvincible = true;

        // 获取 UIOpacity 组件
        const uiOpacity = this.node.getComponent(UIOpacity) || this.node.addComponent(UIOpacity);
        uiOpacity.opacity = 255; // 初始透明度

        // 闪烁逻辑
        const blinkInterval = 0.1; // 闪烁间隔时间
        const blinkCount = Math.floor(duration / blinkInterval);

        // 使用 tween 实现闪烁
        let blinkTween: Tween<UIOpacity> = null;
        blinkTween = tween(uiOpacity)
            .repeat(blinkCount,
                tween()
                    .to(blinkInterval, { opacity: 0 }) // 透明度变为 100
                    .to(blinkInterval, { opacity: 255 }) // 透明度恢复为 255
            )
            .call(() => {
                this.isInvincible = false; // 无敌状态结束
            })
            .start();

        // 设置无敌状态结束
        this.scheduleOnce(() => {
            if (blinkTween) blinkTween.stop(); // 停止闪烁
            uiOpacity.opacity = 255; // 恢复透明度
            this.isInvincible = false;
        }, duration);
    }

    onPlayerDie(param: { isDie: boolean }) {
        if (this.playerSpine) {
            if (param.isDie) {
                let aniName = 'die';
                Common.instance.playSpine(this.playerSpine, aniName, false);
            }
            else {
                this.playerSpine.paused = true;
            }
        }
        this.stopShoot();
    }
}
